﻿using System;
using System.Web.Mvc;
using System.Collections.Generic;
using System.Web.Routing;

namespace ValidationFramework.Web.MVC.Extensions
{
	public static class ValidatedFormExtensions
	{
		/// <summary>
		/// Beings a form generating client scripts for the 
		/// </summary>
		/// <param name="self"></param>
		/// <returns></returns>
		public static MvcValidatedForm BeginValidatedForm(this HtmlHelper self)
		{
			var builder = new TagBuilder("form");

			// Client scripts need a form ID, generate it if needed
			builder.MergeAttribute("id", Guid.NewGuid().ToString(), false);

			var formID = builder.Attributes["id"];

			builder.Attributes["action"] = self.ViewContext.HttpContext.Request.Url.ToString();
			builder.Attributes["method"] = HtmlHelper.GetFormMethodString(FormMethod.Post);

			self.ViewContext.HttpContext.Response.Write(builder.ToString(TagRenderMode.StartTag));

			var script = ClientValidation.GenerateScripts(formID, self.ViewContext.ViewData.Model.GetType());
			return new MvcValidatedForm(self.ViewContext.HttpContext.Response, script);
		}


		public static MvcValidatedForm BeginValidatedForm(this HtmlHelper self, object values)
		{
			return self.BeginValidatedForm(null, null, new RouteValueDictionary(values), FormMethod.Post, new RouteValueDictionary());
		}

		public static MvcValidatedForm BeginValidatedForm(this HtmlHelper self, RouteValueDictionary values)
		{
			return self.BeginValidatedForm(null, null, values, FormMethod.Post, new RouteValueDictionary());
		}

		public static MvcValidatedForm BeginValidatedForm(this HtmlHelper self, string actionName, string controllerName)
		{
			return self.BeginValidatedForm(actionName, controllerName, new RouteValueDictionary(), FormMethod.Post, new RouteValueDictionary());
		}

		public static MvcValidatedForm BeginValidatedForm(this HtmlHelper self, string actionName, string controllerName, object values)
		{
			return self.BeginValidatedForm(actionName, controllerName, new RouteValueDictionary(values), FormMethod.Post, new RouteValueDictionary());
		}

		public static MvcValidatedForm BeginValidatedForm(this HtmlHelper self, string actionName, string controllerName, FormMethod method)
		{
			return self.BeginValidatedForm(actionName, controllerName, new RouteValueDictionary(), method, new RouteValueDictionary());
		}

		public static MvcValidatedForm BeginValidatedForm(this HtmlHelper self, string actionName, string controllerName, RouteValueDictionary values)
		{
			return self.BeginValidatedForm(actionName, controllerName, values, FormMethod.Post, new RouteValueDictionary());
		}

		public static MvcValidatedForm BeginValidatedForm(this HtmlHelper self, string actionName, string controllerName, object values, FormMethod method)
		{
			return self.BeginValidatedForm(actionName, controllerName, values, method, new RouteValueDictionary());
		}

		public static MvcValidatedForm BeginValidatedForm(this HtmlHelper self, string actionName, string controllerName, FormMethod method, IDictionary<string, object> htmlAttributes)
		{
			return self.BeginValidatedForm(actionName, controllerName, new RouteValueDictionary(), method, htmlAttributes);
		}

		public static MvcValidatedForm BeginValidatedForm(this HtmlHelper self, string actionName, string controllerName, FormMethod method, object htmlAttributes)
		{
			return self.BeginValidatedForm(actionName, controllerName, new RouteValueDictionary(), method, new RouteValueDictionary(htmlAttributes));
		}

		public static MvcValidatedForm BeginValidatedForm(this HtmlHelper self, string actionName, string controllerName, RouteValueDictionary values, FormMethod method)
		{
			return self.BeginValidatedForm(actionName, controllerName, values, method, new RouteValueDictionary());
		}

		public static MvcValidatedForm BeginValidatedForm(this HtmlHelper self, string actionName, string controllerName, object values, FormMethod method, object htmlAttributes)
		{
			return self.BeginValidatedForm(actionName, controllerName, new RouteValueDictionary(values), method, new RouteValueDictionary(htmlAttributes));
		}

		public static MvcValidatedForm BeginValidatedForm(this HtmlHelper self, string actionName, string controllerName, RouteValueDictionary values, FormMethod method, IDictionary<string, object> htmlAttributes)
		{
			var builder = new TagBuilder("form");
			builder.MergeAttributes<string, object>(htmlAttributes);

			// Client scripts need a form ID, generate one if needed
			builder.MergeAttribute("id", Guid.NewGuid().ToString(), false);
			var formID = builder.Attributes["id"];

			var routeValues = new RouteValueDictionary(values);
			var urlHelper = new UrlHelper(new RequestContext(self.ViewContext.HttpContext, self.ViewContext.RouteData));

			string actionUrl = urlHelper.Action(actionName, controllerName, routeValues);

			builder.MergeAttribute("action", actionUrl);
			builder.MergeAttribute("method", HtmlHelper.GetFormMethodString(method));

			self.ViewContext.HttpContext.Response.Write(builder.ToString(TagRenderMode.StartTag));

			var script = ClientValidation.GenerateScripts(formID, self.ViewContext.ViewData.Model.GetType());
			return new MvcValidatedForm(self.ViewContext.HttpContext.Response, script);
		}

		public static void EndValidatedForm(this HtmlHelper htmlHelper)
		{
			htmlHelper.ViewContext.HttpContext.Response.Write("</form>");
		}

	}
}
